package star.cloud.asme.system.user;

import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import star.cloud.asme.base.dto.Result;
import star.cloud.asme.base.file.easyExcel.EasyExcelService;
import star.cloud.asme.base.file.fileInfo.FileInfo;
import star.cloud.asme.base.file.fileInfo.FileInfoService;
import star.cloud.asme.base.mybatis.IBaseServiceImpl;
import star.cloud.asme.base.utils.ObjectsUtil;
import star.cloud.asme.system.department.DepartmentService;
import star.cloud.asme.system.user.excel.UserDTO;
import star.cloud.asme.system.user.excel.UserImportListener;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl extends IBaseServiceImpl<UserMapper, User> implements UserService {

    private final UserMapper userMapper;
    private final DepartmentService departmentService;
    private final PasswordEncoder passwordEncoder;
    private final EasyExcelService<UserDTO> easyExcelService;
    private final UserImportListener userImportListener;
    private final FileInfoService fileInfoService;

    @Override
    public Result<User> getOneByCondition(String columnName, Object columnValue) {
        User user = super.getOneByCondition(columnName, columnValue).getBody();
        if (user != null) {
            user.toSafe();
            setDepartment(user);
            setCreatorAndUpdater(user);
            FileInfo fileInfo = fileInfoService.getFileInfoByKeyword(user.getHeadImageUuid());
            if (ObjectsUtil.noNull(fileInfo)) {
                user.setHeadImageUrl(fileInfo.getUrl());
            }
        }
        return Result.ok(user);
    }

    @Override
    public Result<List<User>> getListByCondition(String columnName, Object columnValue) {
        List<User> userList = super.getListByCondition(columnName, columnValue).getBody();
        userList.forEach(user -> {
            setDepartment(user);
            setCreatorAndUpdater(user);
        });
        return Result.ok(userList);
    }

    @Override
    public Result<List<User>> getListByConditions(User conditions) {
        if (conditions.getDeleted()) {
            return Result.ok(userMapper.selectListDeleted());
        } else {
            LambdaQueryWrapper<User> lambdaQueryWrapper = createLambdaQueryWrapper(conditions);
            return Result.ok(userMapper.selectList(lambdaQueryWrapper));
        }
    }

    @Override
    public Result<IPage<User>> getListByConditionsWithPage(User conditions) {
        IPage<User> iPage = new Page<>(conditions.getCurrentPage(), conditions.getPageSize());
        if (conditions.getDeleted()) {
            List<User> users = userMapper.selectListDeleted();
            iPage.setTotal(users.size());
            int fromIndex = (conditions.getCurrentPage() - 1) * conditions.getPageSize();
            int toIndex = Math.min(users.size(), fromIndex + conditions.getPageSize());
            iPage.setRecords(users.subList(fromIndex, toIndex));
        } else {
            userMapper.selectPage(iPage, createLambdaQueryWrapper(conditions));
        }

        iPage.getRecords().forEach(user -> {
            user.setDepartment(departmentService.getById(user.getDepartmentId()));
            setCreatorAndUpdater(user);
        });
        return Result.ok(iPage);
    }

    @Override
    public Result<User> insertOne(User entity) {
        if (getOneByCondition("username", entity.getUsername()).getBody() != null) {
            return Result.error(entity).msg("用户名已经存在");
        }

        if (getOneByCondition("email", entity.getEmail()).getBody() != null) {
            return Result.error(entity).msg("邮箱已经存在");
        }

        if (getOneByCondition("idCard", entity.getIdCard()).getBody() != null) {
            return Result.error(entity).msg("身份证已经存在");
        }

        if (getOneByCondition("phone", entity.getPhone()).getBody() != null) {
            return Result.error(entity).msg("电话号码已经存在");
        }

        if (getOneByCondition("workNo", entity.getWorkNo()).getBody() != null) {
            return Result.error(entity).msg("工号已经存在");
        }

        entity.setHeadImageUuid(UUID.randomUUID().toString());

        if (entity.getPassword() == null) {
            entity.setPassword(passwordEncoder.encode("admin12345678"));
        }

        try {
            int inserted = userMapper.insert(entity);
            if (inserted > 0) {
                setDepartment(entity);
                setCreatorAndUpdater(entity);
                return Result.ok(entity).msg("新增用户成功。");
            } else {
                return Result.error(entity).msg("新增用户失败。");
            }
        } catch (RuntimeException e) {
            return Result.error(entity).msg("新增用户失败，详细信息是，" + e.getMessage());
        }

    }

    @Override
    public Result<User> updateOne(User entity) {
        if (entity.getUsername() != null && !entity.getUsername().isEmpty() && getOneByConditionAndNotId("username", entity.getUsername(), entity.getId()).getBody() != null) {
            return Result.error(entity).msg("用户名已经存在");
        }

        if (entity.getEmail() != null && !entity.getEmail().isEmpty() && getOneByConditionAndNotId("email", entity.getEmail(), entity.getId()).getBody() != null) {
            return Result.error(entity).msg("邮箱已经存在");
        }

        if (entity.getIdCard() != null && !entity.getIdCard().isEmpty() && getOneByConditionAndNotId("idCard", entity.getIdCard(), entity.getId()).getBody() != null) {
            return Result.error(entity).msg("身份证已经存在");
        }

        if (entity.getPhone() != null && !entity.getPhone().isEmpty() && getOneByConditionAndNotId("phone", entity.getPhone(), entity.getId()).getBody() != null) {
            return Result.error(entity).msg("电话号码已经存在");
        }

        if (entity.getWorkNo() != null && !entity.getWorkNo().isEmpty() && getOneByConditionAndNotId("workNo", entity.getWorkNo(), entity.getId()).getBody() != null) {
            return Result.error(entity).msg("工号已经存在");
        }
        try {
            setVersion(entity);
            int updated = userMapper.updateById(entity);
            if (updated > 0) {
                setDepartment(entity);
                setCreatorAndUpdater(entity);
                return Result.ok(entity).msg("更新用户成功。");
            } else {
                return Result.error(entity).msg("更新用户失败。");
            }
        } catch (RuntimeException e) {
            return Result.error(entity).msg("更新用户失败，详细信息是，" + e.getMessage());
        }
    }

    @Override
    public void exportToExcel(HttpServletResponse response) {
        List<User> users = userMapper.selectList(null);
        List<UserDTO> userExports = new ArrayList<>();
        for (User user : users) {
            UserDTO userExport = new UserDTO();
            BeanUtils.copyProperties(user, userExport);
            userExports.add(userExport);
        }
        easyExcelService.exportData(response, UserDTO.class, userExports, "用户清单");
    }

    @Override
    public void importFromExcel(Long creator, MultipartFile file) {
        try {
            easyExcelService.importData(file, UserDTO.class, userImportListener);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public List<String> myListButtonsByUsername(String username) {
        return UserService.super.myListButtonsByUsername(username);
    }

    @Override
    public LambdaQueryWrapper<User> createLambdaQueryWrapper(User user) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper//
                .like(StringUtils.isNotBlank(user.getName()), User::getName, user.getName())//
                .like(StringUtils.isNotBlank(user.getUsername()), User::getUsername, user.getUsername())//
                .like(StringUtils.isNotBlank(user.getIdCard()), User::getIdCard, user.getIdCard())//
                .like(StringUtils.isNotBlank(user.getPhone()), User::getPhone, user.getPhone())//
                .like(StringUtils.isNotBlank(user.getWorkNo()), User::getWorkNo, user.getWorkNo())//
                .eq(ObjectsUtil.noNullAndEmpty(user.getGender()), User::getGender, user.getGender())//
                .eq(ObjectsUtil.noNullAndEmpty(user.getEducationLevel()), User::getEducationLevel, user.getEducationLevel())//
                .like(StringUtils.isNotBlank(user.getGraduateSchool()), User::getGraduateSchool, user.getGraduateSchool())//
                .like(StringUtils.isNotBlank(user.getMajor()), User::getMajor, user.getMajor())//
                .in(user.getIncludeAfter() && user.getDepartmentId() != null, User::getDepartmentId, departmentService.getChildrenIdsById(user.getDepartmentId()))//
                .eq(!user.getIncludeAfter() && user.getDepartmentId() != null, User::getDepartmentId, user.getDepartmentId());
        return lambdaQueryWrapper;
    }

    @Override
    public Result<List<User>> myListUserIdAndUsername() {
        List<User> users = userMapper.selectUserIdAndUserName();
        return Result.ok(users);
    }

    @Override
    public String getNameByUsername(String username) {
        if (username == null || username.isEmpty()) {
            return "";
        } else {
            User user = userMapper.selectOneByUsername(username);
            return user.getName();
        }
    }

    @Override
    public String getWorkNoAndNameByUsername(String username) {
        if (username == null || username.isEmpty()) {
            return "";
        } else {
            User user = userMapper.selectOneByUsername(username);
            return user.getWorkNo() + "-" + user.getName();
        }
    }

    @Override
    public String getEmailByUsername(String username) {
        User user = userMapper.selectOneByUsername(username);
        return user.getEmail();
    }

    private void setDepartment(User entity) {
        if (entity.getDepartmentId() != null) {
            entity.setDepartment(departmentService.getById(entity.getDepartmentId()));
        }
    }

    private Result<User> getOneByConditionAndNotId(String conditionParamName, Object conditionParamValue, Long id) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        switch (conditionParamName) {
            case "username" -> queryWrapper.eq(User::getUsername, conditionParamValue);
            case "workNo" -> queryWrapper.eq(User::getWorkNo, conditionParamValue);
            case "phone" -> queryWrapper.eq(User::getPhone, conditionParamValue);
            case "idCard" -> queryWrapper.eq(User::getIdCard, conditionParamValue);
            case "email" -> queryWrapper.eq(User::getEmail, conditionParamValue);
            default -> log.info("getOneByConditionAndNotId的条件不存在");
        }
        queryWrapper.ne(User::getId, id);
        User user = userMapper.selectOne(queryWrapper);
        return Result.ok(user);
    }

}